import {createAsyncThunk, createEntityAdapter, createSelector, createSlice} from "@reduxjs/toolkit";
import {client} from "../../api/client";

// const initialState = {
//   posts: [],
//   status: 'idle',
//   error: null
// }

const postsAdapter = createEntityAdapter({
  sortComparer: (a, b) => b.date.localeCompare(a.date)
})

const initialState = postsAdapter.getInitialState({
  status: 'idle',
  error: null
})

export const addNewPost = createAsyncThunk('posts/addNewPost', async initialPost => {
  const res = await client.post('/fakeApi/posts', initialPost)
  return res.data
})

const postSlice = createSlice({
  name: 'postSlice',
  initialState,
  reducers: {
    // 旧版使用硬编码模式的添加文章逻辑
    // postAdded: {
    //   reducer(state, action) {
    //     state.posts.push(action.payload)
    //   },
    //   prepare(title, content, userId) {
    //     return {
    //       payload: {
    //         id: nanoid(),
    //         date: new Date().toISOString(),
    //         title,
    //         content,
    //         user: userId,
    //         reactions: {
    //           thumbsUp: 0,
    //           hooray: 0,
    //           heart: 0,
    //           rocket: 0,
    //           eyes: 0
    //         }
    //       }
    //     }
    //   }
    // },
    postUpdated (state, action) {
      const { id, title, content } = action.payload
      // const existingPost = state.posts.find(post => post.id === id)
      const existingPost = state.entities[id]
      if (existingPost) {
        existingPost.title = title
        existingPost.content = content
      }
    },
    reactionAdded (state, action) {
      const { postId, reaction } = action.payload
      // const existingPost = state.posts.find(post => post.id === postId)
      const existingPost = state.entities[postId]
      if (existingPost) {
        existingPost.reactions[reaction]++
      }
    }
  },
  extraReducers (builder) {
    builder
      .addCase(fetchPosts.pending, (state, action) => {
        // fetchPosts.pending请求发送中，
        state.status = 'loading'
      })
      .addCase(fetchPosts.fulfilled, (state, action) => {
        // fetchPosts.fulfilled请求成功
        state.status = 'succeeded'
        // state.posts = state.posts.concat(action.payload)
        postsAdapter.upsertMany(state, action.payload)
      })
      .addCase(fetchPosts.rejected, (state, action) => {
        // fetchPosts.rejected请求失败
        state.status = 'failed'
        state.error = action.error.message
      })
      .addCase(addNewPost.fulfilled, postsAdapter.addOne)
  }
})

/**
 * 使用redux官方提供的mock接口请求数据
 * @type {AsyncThunk<Promise<*>, void, AsyncThunkConfig>}
 */
export const fetchPosts = createAsyncThunk('posts/fetchPosts', async () => {
  const res = await client.get('/fakeApi/posts')
  return res.data
})

// export const selectAllPosts = state => state.posts

// export const selectPostById = (state, postId) => {
//   // console.log(state.posts.posts)
//   return state.posts.posts.find(post => {
//     return post.id === postId
//   })
// }


export const { postAdded, postUpdated, reactionAdded } = postSlice.actions
export default postSlice.reducer

export const {
  selectAll: selectAllPosts,
  selectById: selectPostById,
  selectIds: selectPostIds
} = postsAdapter.getSelectors(state => state.posts)

export const selectPostsByUser = createSelector(
  [selectAllPosts, (state, userId) => userId],
  (posts, userId) => posts.filter(post => post.user === userId)
)
